//
//  NSString+Arithmetic.m
//  KLCurrency
//
//  Created by apple on 2017/12/3.
//  Copyright © 2017年 bonc. All rights reserved.
//

#import "NSString+Arithmetic.h"

static NSString *const operatorAdd =  @"+";
static NSString *const operatorSubtract =  @"−";
static NSString *const operatorMutiply =  @"×";
static NSString *const operatorDivide =  @"÷";
static NSString *const decimalPoint =  @".";

static const NSInteger defaultCaculationStrLength = 40;//默认运算式字符串最大长度
static const NSInteger defaultNumberStrLength = 20;//默认数字字符串最大长度
static const NSInteger defaultAfterDecimalPointStrLength = 3;//默认小数点字符串最大长度

@implementation NSString (Arithmetic)

+ (NSString *)convertToDecimalStyleFromEditingString:(NSString *)str{
    //研究一下
    //                NSNumberFormatterRoundCeiling = kCFNumberFormatterRoundCeiling,
    //                NSNumberFormatterRoundFloor = kCFNumberFormatterRoundFloor,
    //                NSNumberFormatterRoundDown = kCFNumberFormatterRoundDown,
    //                NSNumberFormatterRoundUp = kCFNumberFormatterRoundUp,
    //                NSNumberFormatterRoundHalfEven = kCFNumberFormatterRoundHalfEven,
    //                NSNumberFormatterRoundHalfDown = kCFNumberFormatterRoundHalfDown,
    //                NSNumberFormatterRoundHalfUp = kCFNumberFormatterRoundHalfUp
    if (str==nil||[str isEqualToString:@""]) {
        return @"";
    }else{
        NSRange range= [str rangeOfString:@"."];
        
        if (range.location != NSNotFound) {
            //如果有小数点要进行特殊处理 NSNumberFormatter可能不保留小数点
            NSString *decimal = [str substringFromIndex:range.location];
            NSString *beforeDecimalStr = [str substringToIndex:range.location];
            double amount = [beforeDecimalStr doubleValue];
            NSNumber *f2 = [NSNumber numberWithDouble:amount];
            NSNumberFormatter *numf = [[NSNumberFormatter alloc] init];
            numf.numberStyle = NSNumberFormatterDecimalStyle;
            numf.roundingMode = NSNumberFormatterRoundHalfEven;
            NSString *beforeDecimalResult = [numf stringFromNumber:f2];
            return [NSString stringWithFormat:@"%@%@",beforeDecimalResult,decimal];
        } else {
            double amount = [str doubleValue];
            NSNumber *f2 = [NSNumber numberWithDouble:amount];
            NSNumberFormatter *numf = [[NSNumberFormatter alloc] init];
            numf.numberStyle = NSNumberFormatterDecimalStyle;
            numf.roundingMode = NSNumberFormatterRoundHalfEven;
            NSString *result = [numf stringFromNumber:f2];
            return result;
        }
    }
}


+ (NSString *)convertToDecimalStyleWithTwoDigitsFromString:(NSString *)str{
    if (str==nil||[str isEqualToString:@""]) {
        return @"";
    }else{
        double amount = [str doubleValue];
        NSNumber *f2 = [NSNumber numberWithDouble:amount];
        NSNumberFormatter *numf = [[NSNumberFormatter alloc] init];
        numf.numberStyle = NSNumberFormatterDecimalStyle;
        numf.roundingMode = NSNumberFormatterRoundHalfEven;
        [numf setMinimumFractionDigits:2];
        [numf setMaximumFractionDigits:2];
        NSString *result = [numf stringFromNumber:f2];
        return result;
    }
}

+ (NSString *)transformToPinyin:(NSString *)chinese
{
    NSMutableString *pinyin = [chinese mutableCopy];
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformStripCombiningMarks, NO);
    KLLog(@"%@", pinyin);
    return [pinyin lowercaseString];
}

+ (BOOL)containOperatorInString:(NSString *)str {
    if ([str containsString:operatorAdd] || [str containsString:operatorSubtract]||[str containsString:operatorMutiply] || [str containsString:operatorDivide]) {
        return YES;
    } else {
        return NO;
    }
}

#pragma mark - single number
//判断输入后是否是合法输入单个数字
+ (BOOL)illegalSingleNumber:(NSString *)originSingleNumberText withInput:(NSString *)input {
    //当前数量框中字符串
    if (input == nil) {
        //删除按钮
        if (originSingleNumberText.length == 0 || originSingleNumberText == nil) {
            //空字符串不支持删除
            return YES;
        }
    } else if ([input isEqualToString:@"."]) {
            //非法输入判断
            if ([originSingleNumberText containsString:@"."]) {
                //".."
                return YES;
            }else{
                return [[self class] illegalSingleNumberLength:originSingleNumberText withInput:input];
            }
    } else if ([input isEqualToString:@"0"]) {
        if ([originSingleNumberText isEqualToString:@"0"]) {
            //"00"
            return YES;
        } else {
            return [[self class] illegalSingleNumberLength:originSingleNumberText withInput:input];
        }
    } else {
        return [[self class] illegalSingleNumberLength:originSingleNumberText withInput:input];
    }
    return NO;
}

+ (BOOL)illegalSingleNumberLength:(NSString *)originSingleNumberText withInput:(NSString *)input {
    //增加字符
    //先进行输入上限判断，最长输入20个字符。小数点后最多保留defaultAfterDecimalPointStrLength位
    if (originSingleNumberText.length >= defaultNumberStrLength) {
        //最长输入20个字符
        return YES;
    } else if ([originSingleNumberText containsString:@"."]) {
        //小数点后最多输入defaultAfterDecimalPointStrLength位
        if (originSingleNumberText.length >= defaultAfterDecimalPointStrLength) {
            NSString *str2 = [originSingleNumberText mutableCopy];
            NSString * judgeStr = [str2 substringToIndex:str2.length - defaultAfterDecimalPointStrLength];
            if ([judgeStr containsString:@"."]) {
                return YES;
            }
        }
    }
    return NO;
}


+ (NSString *)changeSingleNumber:(NSString *)originSingleNumberText withInput:(NSString *)input {
    if (originSingleNumberText == nil) {
        originSingleNumberText = @"";
    }
    NSString *result = [[NSString alloc] init];
    
    if (input == nil) {
        //删除字符
        if (originSingleNumberText.length == 1){
            result = @"";
        } else if (originSingleNumberText.length > 1) {
            result = [originSingleNumberText substringToIndex:originSingleNumberText.length - 1];
        }
    } else {
        //增加字符
        if (originSingleNumberText.length == 0) {
            if ([input isEqualToString:@"."]) {
                //"."->"0."
                result = @"0.";
            } else {
                //"1"->"1"
                result = input;
            }
        }else if ([originSingleNumberText isEqualToString:@"0"] && ![input isEqualToString:@"."]) {
            //"01"->"1"
            result = input;
        } else {
            //"12"->"12"
            result = [originSingleNumberText stringByAppendingString:input];
        }
    }
    if ([result isEqualToString:@""]) {
        return nil;
    } else {
        return result;
    }
}

+ (BOOL)illegalArithmeticText:(NSString *)originArithmeticText withInput:(NSString *)input {
    //最后一个运算符 初始化为空
    NSString *lastOperator = nil;
    NSRange range;
    range.length = 1;
    //运算式需要接受数字 运算符 小数点 删除符号的考验
    if (originArithmeticText.length == 0) {
        //如果当期输入为空，输入第一个运算符，没有进行任何运算，无论如何都是合法的
        //如果是空或者只留第一个数字，要切换输入焦点，这个交给cell判断
        return NO;
    } else {
        //如果有输入 进行拆分判断
        //从后往前遍历字符，找到最后一个运算符
        for (NSInteger index = originArithmeticText.length - 1; index >= 0; index--) {
            range.location = index;
            lastOperator = [originArithmeticText substringWithRange:range];
            if ([kOperators containsObject:lastOperator]) {
                //找到最后一个运算符，跳出循环
                break;
            }
        }
        //判断输入字符
        if (input == nil) {
            //如果是删除，正常删除
            return NO;
        } else {
            //如果是输入
            //先进行输入上限判断，最长输入40个字符。小数点后最多保留defaultAfterDecimalPointStrLength位
            if (originArithmeticText.length >= defaultCaculationStrLength) {
                //最长输入40个字符
                return YES;
            }  else {
                //如果是输入，正常输入
                if (range.location == 0) {
                    //没有找到运算符，说明是纯数字，切换焦点
                    return NO;
                } else if (range.location == originArithmeticText.length - 1) {
                    //如果最后一个是运算符，支持继续输入
                    return NO;
                } else {
                    //最后一个运算符在中间
                    //获取最后一个输入数字
                    if ([kOperators containsObject:input]) {
                        //如果继续输入运算符，正常输入，这里要检查前面是否出现了÷0或者÷0. 要过滤，注意这边限制了小数点位数，暂用kMinFloat控制
                        if ([lastOperator isEqualToString:@"÷"]) {
                            NSString *lastStr = [originArithmeticText substringFromIndex:range.location + 1];
                            if ([lastStr isEqualToString:@"0"]||[lastStr isEqualToString:@"0."]||lastStr.floatValue<kMinFloat) {
                                return YES;
                            }
                        }
                        return NO;
                    } else {
                        //如果输入的数字、小数点
                        NSString *lastStr = [originArithmeticText substringFromIndex:range.location + 1];
                        //转变为最后一个数字判断
                        return [NSString illegalSingleNumber:lastStr withInput:input];
                    }
                }
            }
        }
    }
    return NO;
}

+ (NSString *)changeArithmeticText:(NSString *)originArithmeticText withInput:(NSString *)input {
    NSString *result;
    if (input == nil) {
        //如果是删除操作
        if ([originArithmeticText isEqualToString:@""] ||originArithmeticText == nil) {
            result = nil;
        } else {
            result = [originArithmeticText substringToIndex:originArithmeticText.length - 1];
        }
    } else {
        //如果是输入操作
        if ([kOperators containsObject:input]) {
            //如果输入是运算符号
            if ([originArithmeticText isEqualToString:@""] ||originArithmeticText == nil) {
                //如果开始没有输入，补0
                result = [NSString stringWithFormat:@"0%@",input];
            } else if ([kOperators containsObject:[originArithmeticText substringFromIndex:originArithmeticText.length - 1]] ) {
                //如果最后一位是运算符,替换成最新输入的运算符
                result = [NSString stringWithFormat:@"%@%@", [originArithmeticText substringToIndex:originArithmeticText.length - 1], input];
            } else if ([[originArithmeticText substringFromIndex:originArithmeticText.length - 1] isEqualToString:@"."]) {
                //如果最后一位是小数点,替换成最新输入的运算符
                result = [NSString stringWithFormat:@"%@%@", [originArithmeticText substringToIndex:originArithmeticText.length - 1], input];
            } else {
                //如果最后一位是纯数字，直接拼接
                result = [NSString stringWithFormat:@"%@%@", originArithmeticText, input];
            }
        } else {
            //最后一位输入的是数字 或小数点
            NSString *lastOperator = nil;
            NSRange range;
            range.length = 1;
    
            //如果有输入 进行拆分判断
            //从后往前遍历字符，找到最后一个运算符
            for (NSInteger index = originArithmeticText.length - 1; index >= 0; index--) {
                range.location = index;
                lastOperator = [originArithmeticText substringWithRange:range];
                if ([kOperators containsObject:lastOperator]) {
                    //找到最后一个运算符，跳出循环
                    break;
                }
            }
            
            //如果输入的数字、小数点
            NSString *preStr = [originArithmeticText substringToIndex:range.location + 1];
            NSString *lastStr = [originArithmeticText substringFromIndex:range.location + 1];

            NSString *newLastStr = [NSString changeSingleNumber:lastStr withInput:input];
            result = [NSString stringWithFormat:@"%@%@",preStr, newLastStr];
        }
    }
    return result;
}

+ (NSString *)calculateArithmeticTextValue:(NSString *)originArithmeticText {
    
    NSString *newArithmeticText;
    
    if ([kOperators containsObject:[originArithmeticText substringFromIndex:originArithmeticText.length - 1]]) {
        //如果最后一个是运算符
        newArithmeticText = [originArithmeticText substringToIndex:originArithmeticText.length - 1];
    } else {
        //最后一个是数字
        //最后一位输入的是数字 或小数点
        NSString *lastOperator = nil;
        NSRange range;
        range.length = 1;
        
        //如果有输入 进行拆分判断
        //从后往前遍历字符，找到最后一个运算符
        for (NSInteger index = originArithmeticText.length - 1; index >= 0; index--) {
            range.location = index;
            lastOperator = [originArithmeticText substringWithRange:range];
            if ([kOperators containsObject:lastOperator]) {
                //找到最后一个运算符，跳出循环
                break;
            }
        }
        //如果输入的数字、小数点
        NSString *lastStr = [originArithmeticText substringFromIndex:range.location + 1];
        
        if (lastStr.floatValue < kMinFloat) {
            newArithmeticText = [originArithmeticText substringToIndex:range.location];
        } else {
            newArithmeticText = originArithmeticText;
        }
    }

    NSArray *addArray = [newArithmeticText componentsSeparatedByString:operatorAdd];
    double resultValue = 0.0;
    
    for (NSString *str0 in addArray) {
        NSArray *minArray = [str0 componentsSeparatedByString:operatorSubtract];
        double value0 = 0;
        
        for (NSInteger index1 = 0; index1 < minArray.count; index1++) {
            NSString *str1 = minArray[index1];
            NSArray *multiArray = [str1 componentsSeparatedByString:operatorMutiply];
            double value1 = 0;
            
            for (NSInteger index2 = 0; index2 < multiArray.count; index2++) {
                NSString *str2 = multiArray[index2];
                NSArray *diviArray = [str2 componentsSeparatedByString:operatorDivide];
                double value2 = 0;
                
                for (NSInteger index3 = 0; index3 < diviArray.count; index3++) {
                    NSString *str3 = diviArray[index3];
                    
                    if (index3 == 0) {
                        value2 = [str3 doubleValue];
                    } else {
                        if ([str3 doubleValue]) {
                            value2 /= [str3 doubleValue];
                        }
                    }
                }
                
                if (index2 == 0) {
                    value1 = value2;
                } else {
                    value1 *= value2;
                }
            }
            
            if (index1 == 0) {
                value0 = value1;
            } else {
                value0 -= value1;
            }
        }
        resultValue += value0;
    }
    
    if (fabs(resultValue)  < kMinFloat) {
        resultValue = 0;
    }
    
    NSString *resultStr = [NSString stringWithFormat:@"%.2f",resultValue];
    
    return resultStr;
}


@end
